﻿using CoreModule;
using CoreModule.Storages;
using Microsoft.EntityFrameworkCore;
using Microsoft.Win32;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;
using Prism.Mvvm;
using Prism.Regions;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
namespace IdResourceModule.ViewModels
{
    public class PatientListViewModel : BindableBase, IRegionMemberLifetime
    {
        public string Title { get; set; } = string.Empty;
        public bool KeepAlive => false;
        public string PatientName { get; set; } = string.Empty;
        /// <summary>
        /// 
        /// </summary>
        public string IdCard { get; set; } = string.Empty;
        /// <summary>
        /// 
        /// </summary>
        public string SocialCard { get; set; } = string.Empty;
        public int TodayNewNum { get; set; } = 0;
        /// <summary>
        /// 
        /// </summary>
        public int TotalNum { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public string WdCode { get; set; } = string.Empty;
        public ICommand QueryCommand => new Prism.Commands.DelegateCommand(Query);
        public ICommand ResetCommand => new Prism.Commands.DelegateCommand(Reset);
        public ICommand ExportCommand => new Prism.Commands.DelegateCommand(Export);
        public ICommand PageUpdatedCommand => new Prism.Commands.DelegateCommand<object>(PageUpdated);
        public int EntityTotalCount { get; set; } = 0;
        public int DataCountPerPage { get; set; } = 10;
        /// <summary>
        /// 
        /// </summary>
        public int MaxPageCount { get; set; }
        /// <summary>
        /// 
        /// </summary>
        DbStorage DbStorage { get; set; }
        INotifier Notifier { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public PatientListViewModel(DbStorage dbStorage,INotifier notifier)
        {
            DbStorage = dbStorage;
            Notifier = notifier;
            UpdateStatistic();
            this.Query();
        }
         /// <summary>
         /// 
         /// </summary>
        public ObservableCollection<PatientInfo> PatientInfos { get; set; } = new ObservableCollection<PatientInfo>();
        HandyControl.Controls.Pagination Pagination { get; set; }
        /// <summary>
        /// 
        /// </summary>
        public void ResetPaginationPageIndex()
        {
            if (Pagination == null)
            {
                return;
            }
            Pagination.PageIndex = 1;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        public async void PageUpdated(object sender)
        {
            var paginationArgs = sender as HandyControl.Data.FunctionEventArgs<int>;
            var pageIndex = paginationArgs.Info;
            Pagination = paginationArgs.OriginalSource as HandyControl.Controls.Pagination;
            await Query(pageIndex);
        }
        /// <summary>
        /// 
        /// </summary>
        public void Export()
        {
            var String_User_Records = WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.GetLocalizedObject("String_User_Records", null, null) + "";

            if (this.PatientInfos.Count == 0)
            {
                return;
            }
            var entities = new List<PatientInfo>();
            entities.AddRange(this.PatientInfos);
            SaveFileDialog dialog = new SaveFileDialog()
            {
                Filter = "Excel(*.xlsx *.xls)|*.xlsx;*.xls",
                FileName = $"{String_User_Records}{DateTime.Now.ToString("yyyyMMddHHmmss")}"
            };
            string filePath = "";
            if (dialog.ShowDialog().GetValueOrDefault())
            {
                filePath = dialog.FileName;
            }
            var sheetRowCount = 20000;
            if (!string.IsNullOrEmpty(filePath))
            {
                XSSFWorkbook book = new XSSFWorkbook();
                for (int i = 0; i < entities.Count; i += sheetRowCount)
                {
                    CreateSheetForRecord(book, entities.Skip(i).Take(sheetRowCount).ToList());
                }
                 
                using (System.IO.FileStream bookStream = new System.IO.FileStream(filePath, System.IO.FileMode.Create))
                {
                    book.Write(bookStream);
                    bookStream.Close();
                }
                try
                {
                    //System.Diagnostics.Process.Start(dialog.FileName.Replace(dialog.SafeFileName, ""));
                    string pathToFolder = dialog.FileName.Replace(dialog.SafeFileName, "");
                    var psi = new System.Diagnostics.ProcessStartInfo() { FileName = pathToFolder, UseShellExecute = true };
                    System.Diagnostics.Process.Start(psi);
                }
                catch (Exception ex)
                {
                   // Notifier.ShowWarning(ex.Message);
                }
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="list"></param>
        /// <returns></returns>
        private ISheet CreateSheetForRecord(XSSFWorkbook book ,List<PatientInfo> entities)
        {

            var String_Customer_Name = WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.GetLocalizedObject("String_Customer_Name", null, null) + "";
            var String_User_ID = WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.GetLocalizedObject("String_User_ID", null, null) + "";
            var String_Medical_Insurance_Card_Number = WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.GetLocalizedObject("String_Medical_Insurance_Card_Number", null, null) + "";
            var String_ID_Number = WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.GetLocalizedObject("String_ID_Number", null, null) + "";
           
            ISheet sheet = book.CreateSheet();
            IRow rowTitle = sheet.CreateRow(0);
            List<string> names = new List<string>();
            names.Add(String_Customer_Name);
            names.Add(String_User_ID);
            names.Add(String_Medical_Insurance_Card_Number);
            names.Add(String_ID_Number);
           
            for (int i = 0; i < names.Count; i++)
            {
                rowTitle.CreateCell(i).SetCellValue(names[i]);
            }
            sheet.DefaultColumnWidth = 10;
            sheet.SetColumnWidth(1, 25 * 256);
            sheet.SetColumnWidth(2, 25 * 256);
            sheet.SetColumnWidth(3, 25 * 256);
            sheet.SetColumnWidth(4, 25 * 256);
            var index = 1;
            foreach (var entity in entities)
            {
                NPOI.SS.UserModel.IRow itRow = sheet.CreateRow(index);
                List<string> cols = new List<string>();
                cols.Add(entity.PatientName);
                cols.Add(entity.WdCode);
                cols.Add(entity.SocialCard);
                cols.Add(entity.IdCard);
              
                for (int j = 0; j < cols.Count; j++)
                {
                    itRow.CreateCell(j).SetCellValue(cols[j]);
                }
                index = index + 1;
            }
            return sheet;
        }
        /// <summary>
        /// 
        /// </summary>
        public void Reset()
        {
            this.PatientName = string.Empty;
            this.IdCard = string.Empty;
            this.SocialCard = string.Empty;
            this.WdCode = string.Empty;
            this.RaisePropertyChanged(nameof(this.PatientName));
            this.RaisePropertyChanged(nameof(this.IdCard));
            this.RaisePropertyChanged(nameof(this.SocialCard));
            this.RaisePropertyChanged(nameof(this.WdCode));
        }
        public void UpdateStatistic()
        {
            var now = DateTime.Now;
            var beginTime = new DateTime(now.Year, now.Month, now.Day);
            var endTime = new DateTime(now.Year, now.Month, now.Day).AddDays(1);
            try
            {
                this.TodayNewNum = DbStorage.PatientInfos
                    .Count(item => !string.IsNullOrWhiteSpace( item.PatientName ) && item.CreateTime >= beginTime && item.CreateTime <= endTime);
                this.TotalNum = DbStorage.PatientInfos
                    .Where(item=> !string.IsNullOrWhiteSpace(item.PatientName))
                   .Count();
            } catch (Exception ex)
            {
               // Notifier.ShowWarning(ex.Message);
            }
           
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public IQueryable<CoreModule.PatientInfo> CreateQueryable()
        {
            return DbStorage.PatientInfos
                         .Where(item => !string.IsNullOrWhiteSpace(this.PatientName) ? item.PatientName.Contains(this.PatientName) : true)
                         .Where(item => !string.IsNullOrWhiteSpace(this.WdCode) ? item.WdCode.Contains( this.WdCode) : true)
                         .Where(item => !string.IsNullOrWhiteSpace(this.IdCard) ? item.IdCard.Contains( this.IdCard) : true)
                         .Where(item => !string.IsNullOrWhiteSpace(this.SocialCard) ? item.SocialCard.Contains(this.SocialCard) : true)
                         .Where(item => item.IsValid);
                      
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="pageIndex"></param>
        public async Task Query(int pageIndex)
        {
            PatientInfos.Clear();
            try
            {
                EntityTotalCount = await CreateQueryable().CountAsync();
                this.RaisePropertyChanged(nameof(EntityTotalCount));
                MaxPageCount = (int)Math.Ceiling(EntityTotalCount * 1.0 / this.DataCountPerPage);
                this.RaisePropertyChanged(nameof(MaxPageCount));
                var items = await CreateQueryable()
                    .OrderByDescending(item => item.UpdateTime)
                    .Skip((pageIndex - 1) * this.DataCountPerPage)
                    .Take(this.DataCountPerPage)
                    .ToListAsync();
                PatientInfos.AddRange(items);
                this.RaisePropertyChanged(nameof(PatientInfos));
            }
            catch (Exception ex)
            {
               // Notifier.ShowWarning(ex.Message);
            }
        }
        /// <summary>
        /// 
        /// </summary>
        public async void Query()
        {
          await  Query(1);
        }
    }
}
